﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI;
using Medianamik.Core.Sugar;
using Medianamik.Core;

namespace Medianamik.UI.Controls
{
    public class CheckBoxTreeView : BaseMedianamikControl
    {

        #region Fields

        private RadTreeView _treeView = new RadTreeView()
        {
            ID = "items",
            CheckBoxes = true,          
        };

        #endregion

        #region Events
        protected virtual void TreeNodeExpand(object sender, RadTreeNodeEventArgs e)
        {
            NodeExpand(e.Node);
        }
               

        void TreeNodeDataBound(object sender, RadTreeNodeEventArgs e)
        {
            if (!OptionNodeIds.Contains(new Guid(e.Node.Value)))
            {
                e.Node.Category = "Disabled";
                e.Node.CssClass += " rtDisabled";
                e.Node.HoveredCssClass = "rtDisabled";
                e.Node.SelectedCssClass = "rtDisabled";
            }
        }


        #endregion

        #region Properties

        public override Type TypeOfValue
        {
            get { return typeof(IEnumerable<Guid>); }
        }

        public BasePage BasePage
        {
            get
            {
                return (BasePage)base.Page;
            }
        }

        private List<Node> _rootNodes;
        public virtual List<Node> RootNodes
        {
            get
            {
                if (_rootNodes == null)
                {
                    _rootNodes = NodeManager.GetChildNodes( ControlInfo.TreeRootNodeID.GetValueOrDefault(MedianamikModules.ContentManagement));
                    _rootNodes.Sort((n1, n2) => n1.LongPosition.CompareTo(n2.LongPosition));
                    _rootNodes.RemoveAll(n => n.NodeTypeID.Equals(MedianamikTypes.MedianamikSyndication));
                    _rootNodes.RemoveAll(FilterNode);
                }
                return _rootNodes;
            }
        }

        protected virtual Guid[] OptionNodeIds
        {
            get
            {
                return ViewState["OptionNodeIds"] as Guid[]
                    ?? (Guid[])(ViewState["OptionNodeIds"] = Options.Select(o => o.NodeId).ToArray());
            }
        }

                

        #endregion

        #region Methods

        protected  virtual void NodeExpand(RadTreeNode parentNode)
        {
            List<Node> childs = NodeManager.GetChildNodes(new Guid(parentNode.Value));
            childs.Sort((n1, n2) => n1.LongPosition.CompareTo(n2.LongPosition));
            childs.RemoveAll(n => n.NodeTypeID.Equals(MedianamikTypes.MedianamikSyndication));
            childs.RemoveAll(n => FilterNode(n));

            foreach (Node child in childs)
            {
                RadTreeNode nd = new RadTreeNode(child.DisplayName, child.ID.ToString());
                if (child.HasChildren)
                    nd.ExpandMode = TreeNodeExpandMode.ServerSideCallBack;
                if (!OptionNodeIds.Contains(child.ID) || (IsSyndication && !ParentNode.LegitimateChildTypes.Any(t => t.ID.Equals(child.NodeTypeID))))
                {
                    nd.Category = "Disabled";
                    nd.CssClass += " rtDisabled";
                    nd.Checkable = false;
                    nd.HoveredCssClass = "rtDisabled";
                    nd.SelectedCssClass = "rtDisabled";
                }
                parentNode.Nodes.Add(nd);
            }

            parentNode.ExpandMode = TreeNodeExpandMode.ClientSide;
            parentNode.Expanded = true;
        }

        protected virtual bool FilterNode(Medianamik.Core.Node node)
        {
            return false;
        }

        public override object GetValue()
        {
            EnsureChildControls();
            return _treeView.CheckedNodes.Select(i => new Guid(i.Value));
        }

        protected override void CreateControlHierarchy(bool pUseDataSource)
        {
            Controls.Add(_treeView);
            _treeView.EnableEmbeddedSkins = false;
            _treeView.Skin = "Medianamik";
            _treeView.NodeExpand += new RadTreeViewEventHandler(TreeNodeExpand);

            if (pUseDataSource)
            {
                foreach (Node option in RootNodes)
                {
                    RadTreeNode nd = new RadTreeNode(option.DisplayName, option.ID.ToString());
                    if (option.HasChildren)
                        nd.ExpandMode = TreeNodeExpandMode.ServerSideCallBack;

                    if (!OptionNodeIds.Contains(option.ID) || (IsSyndication && ParentNode.LegitimateChildTypes.Any(t => t.ID.Equals(option.NodeTypeID))))
                    {
                        nd.Category = "Disabled";
                        nd.CssClass += " rtDisabled";
                        nd.Checkable = false;
                        nd.HoveredCssClass = "rtDisabled";
                        nd.SelectedCssClass = "rtDisabled";
                    }

                    _treeView.Nodes.Add(nd);
                }

                Guid[] selectedValues = (DataSource as IEnumerable<Guid> ?? Enumerable.Empty<Guid>()).ToArray();
                foreach(var selectedNode in NodeManager.GetNodes(selectedValues) )
                {
                    RadTreeNode treeNode = _treeView.FindNodeByValue(selectedNode.ID.ToString());

                    if (treeNode == null)
                    {
                        List<Guid> parentIds = DataUtil.GetBottomToTopNodeIds(selectedNode.Path, true, 0);
                        parentIds.Reverse();

                        foreach (Guid id in parentIds)
                        {
                            treeNode = _treeView.FindNodeByValue(id.ToString());
                            if (treeNode != null)
                                NodeExpand(treeNode);
                        }

                        treeNode = _treeView.FindNodeByValue(selectedNode.ID.ToString());
                    }

                    if (treeNode != null)
                    {
                        treeNode.Checked = true;
                    }
                }
                
            }
        }

        #endregion

    }
}
